﻿using System;
using System.Threading;
using System.Diagnostics;

using LoginServer.Manager;
using LoginServer.Networking;

namespace LoginServer
{
    class Program
    {
        public static int _AcceptedLogins;
        public static int _PlayerCount;

        private static Thread _ServerThread;
        private static bool _Running = true;
        private static String _ServerKey = "";

        public static string Format = "0";
        public static string Launcher = "0";
        public static string Updater = "0";
        public static string Client = "0";
        public static string Sub = "0";
        public static string Option = "0";

        public static string UpdateUrl = "";

        public static string ServerName = "Reloaded";
        public static string ServerIP = "0.0.0.0";
        public static string ServerToShow = "0";

        public static String ServerKey { get { return _ServerKey; } }

        static void Main(string[] args)
        {
            Console.WindowWidth = Console.LargestWindowWidth - 25;
            Console.WindowHeight = Console.LargestWindowHeight - 25;
            Console.Title = "[LOADING]: LoginServer";
            _Running = Boot();

            _ServerThread = new Thread(new ThreadStart(serverLoop));
            _ServerThread.Priority = ThreadPriority.BelowNormal;
            _ServerThread.Start();
        }

        private static bool Boot()
        {
            try
            {
                _AcceptedLogins = 0;

                Console.Title = "[Booting]: WarRock Reloaded Emulator - Login Server";
                Log.WriteBlank();
                Log.WriteBlank();

                string settingsFile = IO.workingDirectory + @"/settings.ini";
                if (System.IO.File.Exists(settingsFile) == false)
                {
                    Log.WriteError("settings.ini not found at " + settingsFile);
                    return false;
                }

                _ServerKey = IO.readINI("Server", "key", settingsFile);

                string Host = IO.readINI("Database", "host", settingsFile);
                int Port = int.Parse(IO.readINI("Database", "port", settingsFile));
                string Username = IO.readINI("Database", "username", settingsFile);
                string Password = IO.readINI("Database", "password", settingsFile);
                string Database = IO.readINI("Database", "database", settingsFile);
                ServerName = IO.readINI("Server", "name", settingsFile);
                ServerIP = IO.readINI("Server", "ip", settingsFile);
                ServerToShow = IO.readINI("Server", "toshow", settingsFile);
                Format = IO.readINI("Updater", "format", settingsFile);
                Launcher = IO.readINI("Updater", "launcher", settingsFile);
                Updater = IO.readINI("Updater", "updater", settingsFile);
                Client = IO.readINI("Updater", "client", settingsFile);
                Sub = IO.readINI("Updater", "sub", settingsFile);
                Option = IO.readINI("Updater", "option", settingsFile);
                UpdateUrl = IO.readINI("Updater", "url", settingsFile);

                if (DB.openConnection(Host, Port, Database, Username, Password) == false)
                {
                    Console.ReadKey();
                    return false;
                }

                DateTime current = DateTime.Now;
                string nTime = String.Format("{0:dd_MM_yy}", current);

                Log.setup("Log_" + nTime + "_Login.txt");

                BanManager.load();
                RankManager.load();

                Log.WriteBlank();
                
                Log.WriteBlank();

                PacketManager.setup();
                ServerManager.setup(12);

                //if (ServerSocket.openSocket(5010, 5) == false)
                //{
                //    Console.ReadKey();
                //    return false;
                //}

                //Log.WriteBlank();

                GC.Collect();

                if (NetworkSocket.openSocket(5330) == false)
                {
                    Console.ReadKey();
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                Log.WriteError(ex.Message);
                serverLoop();
                return true;
            }
        }

        private static void serverLoop()
        {
            while (_Running)
            {
                int onlineCount = 0;

                foreach(Virtual_Objects.Server.virtualServer Server in ServerManager.getServers())
                {
                    onlineCount += Server.getCount();
                }

                Console.Title = "[RUNNING]: WarRock Reloaded Emulator - Login Server | Ram Usage: " + (GC.GetTotalMemory(false) / 1024) + " KB";
                Thread.Sleep(1500);
            }
        }

        public static long UnixTimestamp
        {
            get
            {
                TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
                return Convert.ToInt64(ts.TotalSeconds);
            }
        }
    }
}
